Passed
Pull Request — main (#12)
by Julia
02:02
created

sorter.js ➔ getTable   A

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
1
/* eslint-disable */
2
var addSorting = (function() {
3
    'use strict';
4
    var cols,
5
        currentSort = {
6
            index: 0,
7
            desc: false
8
        };
9
10
    // returns the summary table element
11
    function getTable() {
12
        return document.querySelector('.coverage-summary');
13
    }
14
    // returns the thead element of the summary table
15
    function getTableHeader() {
16
        return getTable().querySelector('thead tr');
17
    }
18
    // returns the tbody element of the summary table
19
    function getTableBody() {
20
        return getTable().querySelector('tbody');
21
    }
22
    // returns the th element for nth column
23
    function getNthColumn(n) {
24
        return getTableHeader().querySelectorAll('th')[n];
25
    }
26
27
    function onFilterInput() {
28
        const searchValue = document.getElementById('fileSearch').value;
29
        const rows = document.getElementsByTagName('tbody')[0].children;
30
        for (let i = 0; i < rows.length; i++) {
31
            const row = rows[i];
32
            if (
33
                row.textContent
34
                    .toLowerCase()
35
                    .includes(searchValue.toLowerCase())
36
            ) {
37
                row.style.display = '';
38
            } else {
39
                row.style.display = 'none';
40
            }
41
        }
42
    }
43
44
    // loads the search box
45
    function addSearchBox() {
46
        var template = document.getElementById('filterTemplate');
47
        var templateClone = template.content.cloneNode(true);
48
        templateClone.getElementById('fileSearch').oninput = onFilterInput;
49
        template.parentElement.appendChild(templateClone);
50
    }
51
52
    // loads all columns
53
    function loadColumns() {
54
        var colNodes = getTableHeader().querySelectorAll('th'),
55
            colNode,
56
            cols = [],
57
            col,
58
            i;
59
60
        for (i = 0; i < colNodes.length; i += 1) {
61
            colNode = colNodes[i];
62
            col = {
63
                key: colNode.getAttribute('data-col'),
64
                sortable: !colNode.getAttribute('data-nosort'),
65
                type: colNode.getAttribute('data-type') || 'string'
66
            };
67
            cols.push(col);
68
            if (col.sortable) {
69
                col.defaultDescSort = col.type === 'number';
70
                colNode.innerHTML =
71
                    colNode.innerHTML + '<span class="sorter"></span>';
72
            }
73
        }
74
        return cols;
75
    }
76
    // attaches a data attribute to every tr element with an object
77
    // of data values keyed by column name
78
    function loadRowData(tableRow) {
79
        var tableCols = tableRow.querySelectorAll('td'),
80
            colNode,
81
            col,
82
            data = {},
83
            i,
84
            val;
85
        for (i = 0; i < tableCols.length; i += 1) {
86
            colNode = tableCols[i];
87
            col = cols[i];
88
            val = colNode.getAttribute('data-value');
89
            if (col.type === 'number') {
90
                val = Number(val);
91
            }
92
            data[col.key] = val;
93
        }
94
        return data;
95
    }
96
    // loads all row data
97
    function loadData() {
98
        var rows = getTableBody().querySelectorAll('tr'),
99
            i;
100
101
        for (i = 0; i < rows.length; i += 1) {
102
            rows[i].data = loadRowData(rows[i]);
103
        }
104
    }
105
    // sorts the table using the data for the ith column
106
    function sortByIndex(index, desc) {
107
        var key = cols[index].key,
108
            sorter = function(a, b) {
109
                a = a.data[key];
110
                b = b.data[key];
111
                return a < b ? -1 : a > b ? 1 : 0;
112
            },
113
            finalSorter = sorter,
114
            tableBody = document.querySelector('.coverage-summary tbody'),
115
            rowNodes = tableBody.querySelectorAll('tr'),
116
            rows = [],
117
            i;
118
119
        if (desc) {
120
            finalSorter = function(a, b) {
121
                return -1 * sorter(a, b);
122
            };
123
        }
124
125
        for (i = 0; i < rowNodes.length; i += 1) {
126
            rows.push(rowNodes[i]);
127
            tableBody.removeChild(rowNodes[i]);
128
        }
129
130
        rows.sort(finalSorter);
131
132
        for (i = 0; i < rows.length; i += 1) {
133
            tableBody.appendChild(rows[i]);
134
        }
135
    }
136
    // removes sort indicators for current column being sorted
137
    function removeSortIndicators() {
138
        var col = getNthColumn(currentSort.index),
139
            cls = col.className;
140
141
        cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
142
        col.className = cls;
143
    }
144
    // adds sort indicators for current column being sorted
145
    function addSortIndicators() {
146
        getNthColumn(currentSort.index).className += currentSort.desc
147
            ? ' sorted-desc'
148
            : ' sorted';
149
    }
150
    // adds event listeners for all sorter widgets
151
    function enableUI() {
152
        var i,
153
            el,
154
            ithSorter = function ithSorter(i) {
155
                var col = cols[i];
156
157
                return function() {
158
                    var desc = col.defaultDescSort;
159
160
                    if (currentSort.index === i) {
161
                        desc = !currentSort.desc;
162
                    }
163
                    sortByIndex(i, desc);
164
                    removeSortIndicators();
165
                    currentSort.index = i;
166
                    currentSort.desc = desc;
167
                    addSortIndicators();
168
                };
169
            };
170
        for (i = 0; i < cols.length; i += 1) {
171
            if (cols[i].sortable) {
172
                // add the click event handler on the th so users
173
                // dont have to click on those tiny arrows
174
                el = getNthColumn(i).querySelector('.sorter').parentElement;
175
                if (el.addEventListener) {
176
                    el.addEventListener('click', ithSorter(i));
177
                } else {
178
                    el.attachEvent('onclick', ithSorter(i));
179
                }
180
            }
181
        }
182
    }
183
    // adds sorting functionality to the UI
184
    return function() {
185
        if (!getTable()) {
186
            return;
187
        }
188
        cols = loadColumns();
189
        loadData();
190
        addSearchBox();
191
        addSortIndicators();
192
        enableUI();
193
    };
194
})();
195
196
window.addEventListener('load', addSorting);
197